package com.joymart.aftersale.service;

import com.joymart.aftersale.model.AfterSaleSheet;
import com.joymart.common.abstraction.StatusService;
import com.joymart.common.error.handling.JoymartBusinessException;
import com.joymart.common.model.ApprovalStatus;
import com.joymart.common.system.BusinessConfig;
import com.joymart.common.system.IdGenerator;
import com.joymart.common.utils.CollectionUtils;
import com.joymart.common.utils.DatetimeUtils;
import com.joymart.common.utils.SecurityUtils;
import com.joymart.compute.model.OrderGain;
import com.joymart.compute.service.OrderGainService;
import com.joymart.order.model.Order;
import com.joymart.order.service.OrderEventService;
import com.joymart.order.service.OrderService;
import com.joymart.prepaid.wallet.service.PrepaidWalletService;
import com.joymart.wechat.service.WechatOpenPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.jdbc.core.JdbcAggregateTemplate;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.data.relational.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static org.springframework.data.relational.core.query.Criteria.where;

@Service
@Transactional
public class AfterSaleService extends StatusService<AfterSaleSheet, ApprovalStatus> {

    @Autowired
    private IdGenerator idGenerator;
    @Autowired
    private JdbcAggregateTemplate jdbcAggregateTemplate;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderGainService orderGainService;
    @Autowired
    private PrepaidWalletService prepaidWalletService;
    @Autowired
    private OrderEventService orderEventService; //todo
    @Autowired
    private BusinessConfig businessConfig;
    @Value("${wechat.aftersaleResultTemplateId}")
    private String afterSaleResultTemplateId;
    @Autowired
    private WechatOpenPlatformService wechatOpenPlatformService;


    public void createSheet(AfterSaleSheet sheet) {
        Order order = orderService.getById(sheet.getOrderId());
        orderService.checkStatus(order, Order.Status.RECEIVED);
        SecurityUtils.checkCurrentUserIsAny(order::getBuyerId);
        boolean illegal = this.findByOrderId(order.getId()).stream().anyMatch(afterSaleSheet ->
                List.of(ApprovalStatus.APPROVED, ApprovalStatus.PENDING).contains(afterSaleSheet.getStatus()));
        if (illegal) {
            throw  new JoymartBusinessException("当前有正在进行或已经通过的售后申请");
        }

        sheet.setBuyerId(order.getBuyerId());
        sheet.setFirstSellerId(order.getFirstSellerId());
        sheet.setSecondSellerId(order.getSecondSellerId());
        sheet.setId(idGenerator.next());
        sheet.setCreatedAt(DatetimeUtils.now());
        this.modifyStatus(sheet, ApprovalStatus.PENDING);
        jdbcAggregateTemplate.insert(sheet);
    }

    public void approve(String id, String remarkBySeller){
        AfterSaleSheet sheet = jdbcAggregateTemplate.findById(id, AfterSaleSheet.class);
        checkStatus(sheet, ApprovalStatus.PENDING);
        sheet.setRemarkBySeller(remarkBySeller);
        modifyStatus(sheet, ApprovalStatus.APPROVED);
        jdbcAggregateTemplate.save(sheet);
        revertOrderGainFromPrepaidWallet(sheet.getOrderId());
        Map<String, Object> subMsgData =
                Map.of("character_string3", sheet.getOrderId(),
                        "phrase1", "已同意",
                        "thing2", Optional.ofNullable(sheet.getRemarkBySeller())
                                        .filter(StringUtils::hasText)
                                .orElse("店铺已同意您的售后申请"));
        String page = "pages-aftersales/AfterDetails/AfterDetails?id="+sheet.getId();
        wechatOpenPlatformService.sendSubscribeMessage(sheet.getBuyerId(),afterSaleResultTemplateId,subMsgData, page);
    }



    public void reject(String id, String remarkBySeller){
        AfterSaleSheet sheet = jdbcAggregateTemplate.findById(id, AfterSaleSheet.class);
        checkStatus(sheet, ApprovalStatus.PENDING);
        sheet.setRemarkBySeller(remarkBySeller);
        modifyStatus(sheet, ApprovalStatus.REJECTED);
        jdbcAggregateTemplate.save(sheet);
        Map<String, Object> subMsgData =
                Map.of("character_string3", sheet.getOrderId(),
                        "phrase1", "已驳回",
                        "thing2", Optional.ofNullable(sheet.getRemarkBySeller())
                                        .filter(StringUtils::hasText)
                                .orElse("店铺不同意您的售后申请"));
        String page = "pages-aftersales/AfterDetails/AfterDetails?id="+sheet.getId();
        wechatOpenPlatformService.sendSubscribeMessage(sheet.getBuyerId(),afterSaleResultTemplateId,subMsgData, page);
    }

    /**
     * 从预付货款中回滚当初订单获得的收益
     * @param orderId
     */
    private void revertOrderGainFromPrepaidWallet(String orderId) {
        List<OrderGain> orderGains = orderGainService.findByOrderId(orderId);
        orderGains.forEach(orderGain -> {
            String userId = orderGain.getOwnerId();
            BigDecimal amount = orderGain.getAmount();
            prepaidWalletService.decrease(userId, amount.multiply(businessConfig.getPvCashRate(), MathContext.DECIMAL64));
        });
    }
    public void confirmHeadQuarterRefunded(String id){
        AfterSaleSheet sheet = jdbcAggregateTemplate.findById(id, AfterSaleSheet.class);
        checkStatus(sheet, ApprovalStatus.APPROVED);
        if(sheet.isHeadQuarterRefunded()){
            throw new JoymartBusinessException("已经确认，请勿重复操作");
        }
        sheet.setHeadQuarterRefunded(true);
        jdbcAggregateTemplate.save(sheet);
    }

    public void confirmFirstSellerRefunded(String id){
        AfterSaleSheet sheet = jdbcAggregateTemplate.findById(id, AfterSaleSheet.class);
        SecurityUtils.checkCurrentUserIsAny(sheet::getFirstSellerId);
        checkStatus(sheet, ApprovalStatus.APPROVED);
        if(sheet.isFirstSellerRefunded()){
            throw new JoymartBusinessException("已经确认，请勿重复操作");
        }
        sheet.setFirstSellerRefunded(true);
        jdbcAggregateTemplate.save(sheet);
    }

    public void confirmSecondSellerRefunded(String id){
        AfterSaleSheet sheet = jdbcAggregateTemplate.findById(id, AfterSaleSheet.class);
        SecurityUtils.checkCurrentUserIsAny(sheet::getFirstSellerId);
        if(sheet.isSecondSellerRefunded()){
            throw new JoymartBusinessException("已经确认，请勿重复操作");
        }
        checkStatus(sheet, ApprovalStatus.APPROVED);
        sheet.setSecondSellerRefunded(true);
        jdbcAggregateTemplate.save(sheet);
    }


    public AfterSaleSheet findById(String id) {
        return jdbcAggregateTemplate.findById(id, AfterSaleSheet.class);
    }


    public List<AfterSaleSheet> findByOrderId(String orderId) {
        Criteria criteria = where("orderId").is(orderId);
        return CollectionUtils.asList(jdbcAggregateTemplate.findAll(Query.query(criteria), AfterSaleSheet.class));
    }



}
